#include "indirectblock.h"
#include <iostream>
#include <stdio.h>
#include "lib/e7convert.h"

IndirectBlock::IndirectBlock(FILE* device, unsigned long offset, int level) : Block(device, offset)
{
	indirBlocks = new indirect_block_t();
	this->level = level;
	read(indirBlocks, sizeof(indirect_block_t));

}

IndirectBlock::~IndirectBlock()
{
	delete indirBlocks;
}

std::vector<long> * IndirectBlock::getAllAddressBlocks()
{
	std::vector<long> * tmpList = new std::vector<long>();

	for(int i=0; i<INDIRECT_BLOCKS; i++)
	{
		long outp = getlong4(indirBlocks->blocks[i], 0);
		if(level == 1)
		{
			if(outp != 0)
			{
				//cout << "Level 1: " << outp << endl;
				tmpList->push_back(outp);
			}
		}
		else if(level == 2)
		{
			if(outp != 0)
			{
				//cout << "Level 2: " << outp << endl;
				IndirectBlock * ind = new IndirectBlock(device, outp*BLOCKSIZE, 1);
				vector<long> * tmp2 = ind->getAllAddressBlocks();

				for(vector<long>::iterator iter = tmp2->begin(); iter != tmp2->end(); ++iter)
				{
					tmpList->push_back((*iter));
				}

				delete ind;
				delete tmp2;
			}
		}
		else if(level == 3)
		{
			if(outp != 0)
			{
				//cout << "Level 3: " << outp << endl;
				IndirectBlock * ind = new IndirectBlock(device, outp*BLOCKSIZE, 2);
				std::vector<long> * tmp2 = ind->getAllAddressBlocks();

				for(std::vector<long>::iterator iter = tmp2->begin(); iter != tmp2->end(); ++iter)
				{
					tmpList->push_back((*iter));
				}

				delete ind;
				delete tmp2;
			}
		}
	}

	return tmpList;
}

void IndirectBlock::print()
{
	for(int i=0; i<INDIRECT_BLOCKS; i++)
	{
		//cout << indirBlocks->blocks[i] << " ";
		long outp = getlong4(indirBlocks->blocks[i], 0);

		if(level == 1)
		{
			std::cout << outp << " ";
		}
		else if(level == 2)
		{
			std::cout << "[" << outp << "] ";

			if(outp != 0)
			{
				IndirectBlock * ind = new IndirectBlock(device, outp*BLOCKSIZE, 1);
				ind->print();

				delete ind;
			}
		}
		else if(level == 3)
		{
			cout << "[[" << outp << "]] ";

			if(outp != 0)
			{
				IndirectBlock * ind = new IndirectBlock(device, outp*BLOCKSIZE, 2);
				ind->print();

				delete ind;
			}
		}
	}
}
